package com.nts.visionworks.core.security.service;

import java.util.ArrayList;
import java.util.Collection;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nts.visionworks.core.security.domain.SecurityAuthority;
import com.nts.visionworks.core.security.domain.SecurityIdentity;

@Service("userDetailsService")
public class UserDetailsServiceImplement implements UserDetailsService
{
	private final static Logger logger = LoggerFactory.getLogger(UserDetailsServiceImplement.class);
	
	@Resource(name="securityService")
	private SecurityService _securityService;
	
	@Transactional
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException
	{
		try
		{
			SecurityIdentity identity = this._securityService.viewSecurityIdentity(username);
			
			if (identity == null)
			{
				throw new UsernameNotFoundException("The following user credentials do not exist. : " + username);
			}
			
			return toUserDetails(identity);
		}
		catch (Exception error)
		{
			logger.error(error.getMessage(), error);
		}
		
		return null;
	}
	
	private UserDetails toUserDetails(SecurityIdentity identity)
	{
		Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		
		String authorityKey = identity.getSecurityAuthority().getAuthorityKey();
		
		SecurityAuthority authority = this._securityService.viewSecurityAuthority(authorityKey);
		
		SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(authority.getAuthorityKey());
		
		authorities.add(grantedAuthority);
		
		return new User(identity.getSecurityId(), identity.getSecurityPassword(),
						identity.isEnabled(), identity.isExpired(),
						identity.isCredentialExpired(), identity.isLocked(), authorities);
	}
}